home *** CD-ROM | disk | FTP | other *** search
- # SpecTcl, by S. A. Uhler
- # Copyright (c) 1994-1995 Sun Microsystems, Inc.
- #
- # See the file "license.txt" for information on usage and redistribution
- # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
- #
- # manage saving and loading project files
- # this is temporary!
-
- set Version 0.1
- set Id "WidGet file"
- proc save_project {file {compile 0}} {
- dputs "Saving $file"
- global Widgets _Message Id P Current Version
- global Widget_data f
-
- catch {exec "mv -f $file ${file}-old"}
- if {[catch "open $file w" fd]} {
- set _Message "Can't open file $file"
- return 0
- }
- puts $fd "$Id, version $Version, created: [exec date]"
- set Current(project) [file root $file]
- set_title $Current(project)
- set Current(dirty) ""
-
- # compute geometry options (fix padding name clash)
- blt_get .can geom
-
- set f(level) 0
- set_frame_level .can.f
- outline_inhibit 1
- foreach item "f [array names Widgets]" {
- dputs "saving $item to $file"
- set _Message "saving $item"
- update
- puts $fd "Widget $item"
- if {$item == "f"} {
- widget_extract .can.f
- } else {
- widget_extract .can.f.$item
- }
- upvar #0 $item data
- set class $data(type)
- foreach i [array names data] {
-
- # figure out what "type" of option we have
- # since {,i}pad[xy] are used both for geometry
- # and configuration, handle them specially
-
- # skip configuration values that are defaulted!
- # This doesn't catch equivalent forms of the
- # same value
-
- set skip 0
- foreach type "$class geometry table" {
- if {![catch {set default $Widget_data(default:$type,$i)}]} {
- if {[string compare $default [list $data($i)]] == 0} {
- incr skip
- break
- }
- }
- }
- if {$skip} continue
-
- set map $i
- if {[info exists Widget_data(default:$class,$i)]} {
- set type configure
- } elseif {[info exists geom(-$i)]} {
- set type geometry
- } elseif {[string match *wad* $i]} {
- set type geometry
- regsub wad $i pad map
- } elseif {[string match *align $i]} {
- set type geometry
- regsub align $i anchor map
- } else {
- set type other
- }
-
- # run the input conversion filters
- set value $data($i)
- if {[info exists Widget_data(infilter:$i)]} {
- $Widget_data(infilter:$i) value
- dputs "filtering $i"
- }
- puts $fd \t[list $type $map $value]
- }
- }
- outline_inhibit 0
- close $fd
- update idletasks
- if {$compile} {
- set _Message "Generating Tcl code"
- update idletasks
- compile $Current(project).ui $Current(project).ui.tcl
- }
- set _Message "save completed"
- }
-
- # load a project it. Must be in EMPTY grid
- # Well, maybe not!, just avoid name clashes!
- # This should be combined with the widget creation for
- # both mouse-based widget creation and undo
- # This is a temporary hack!!
-
- proc load_project {file {master .can.f}} {
- global Widgets _Message Id Frames P Widget_data Current
-
- set _Message "loading project $file"
- update idletasks
- if {![file readable $file]} {
- set _Message "$file does not exist"
- return 0
- }
-
- set fd [open $file r]
- set line ""
- gets $fd line
- if {[string first $Id $line] != 0} {
- set _Message "$file is not a UI file"
- close $fd
- return 0
- }
-
- # clear the slate, or abort
-
- if {$Current(dirty) != "" || [array names Widgets] != ""} {
- if {![clear_all]} {
- close $fd
- return 0
- }
- }
-
- # read in the sucker!!
-
- set Current(project) [file root $file]
- set_title $Current(project)
- set Current(dirty) ""
-
-
- while {1} {
- gets $fd line
- if {[eof $fd]} break
-
- # gather entire line
-
- while {![info complete $line]} {
- append line \n[gets $fd]
- dputs gulp
- }
-
- # look for a keyword (only widget for now)
-
- if {[string first Widget $line] == 0} {
- set name [lindex $line 1]
- global $name
- set Widgets($name) 1
- continue
- }
- array set $name [lrange $line 1 end]
- }
- close $fd
-
- # create and manage the widgets
- # Sort first, so frames get made first
-
- foreach name [lsort -command sort_widgets2 [array names Widgets]] {
- upvar #0 $name data
- dputs "Making widgets $name"
-
- if {$name == "f"} {
- make_decorations .can.f
- # zap all existing arrows, then create new ones
- continue
- }
-
- update_widget_counters $name
-
- # filter the font
-
- if {[info exists data(font)]} {
- set value $data(font)
- $Widget_data(outfilter:font) dummy font value
- set data(font) $value
- }
-
- # the rows and columns
-
- foreach dim {row column} {
- if {![info exists data($dim)]} {
- set data($dim) 2
- } else {
- set data($dim) [expr $data($dim) * 2]
- }
- }
- # the rows and columns spans
-
- foreach dim {rowspan columnspan} {
- if {![info exists data($dim)]} {
- set data($dim) 1
- } else {
- set data($dim) [expr $data($dim) * 2 -1]
- }
- }
-
- # make the widget, set the bindings
-
- widget_configure $name
- outline_create $name
- widget_extract .can.f.$name ;# add default options to array
- if {[info exists data(resize_row)]} {
- bindtags .can.f.$name "frame widget [bindtags .can.f.$name]"
- make_decorations .can.f.$name
- } else {
- bindtags .can.f.$name "widget [bindtags .can.f.$name]"
- }
-
- set done($name) 1
- }
- arrow_activate .can .can.f
- }
-
- # sort a list of widgets so the "masters" always get made first
- # this will be called from qsort
- # - Frames go in front of widgets
- # - Master frames go in front of their children
-
- proc sort_widgets2 {w1 w2} {
- upvar #0 $w1 a $w2 b
-
- if {$a(type) != "frame" && $b(type) != "frame"} {return 0}
- if {$a(type) != "frame"} {return 1}
- if {$b(type) != "frame"} {return -1}
-
- # both frames look for child master relationship
-
- if {$a(master) == $w2} {return 1}
- if {$b(master) == $w1} {return -1}
- return 0
- }
-
- # make the grid lines, arrows, etc
-
- proc make_decorations {master} {
- global P Frames
- upvar #0 [winfo name $master] data
- grid_create $master [expr 1 + 2 * [llength $data(resize_row)]] \
- [expr 1 + 2 * [llength $data(resize_column)]] \
- $P(grid_size) $P(can_bg)
- blt_table arrange $master
- set Frames($master) 1
- table_setup $master
-
- arrow_create .can_row row $master all
- arrow_create .can_column column $master all
- arrow_shapeall .can $master row
- arrow_shapeall .can $master column
- arrow_activate .can $master
- }
-
- # make sure the Next_widget counters are set properly
- # name: the "itemname"
-
- proc update_widget_counters {name} {
- global Next_widget
- dputs $name
- if {![regexp {([^#]*)#([0-9]*)} $name dummy name count]} return
- dputs $name -> $name $count
- if {[info exists Next_widget($name)] && $Next_widget($name) < $count} {
- dputs $name $count -> $Next_widget($name)
- set Next_widget($name) $count
- }
- }
-